#ifndef _cesium_example_asio_timer_hpp_
#define _cesium_example_asio_timer_hpp_

#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

/** Implementation of the Timer concept using asio. */
class AsioTimer {
public:
    typedef boost::posix_time::time_duration DurationType;
    typedef boost::posix_time::ptime TimeType;

    typedef boost::function0<void> TimerCallback;

    AsioTimer(boost::asio::io_service& ios)
     : io_service(ios)
    {
    }

    AsioTimer(const AsioTimer& cpy)
     : io_service(cpy.io_service)
    {
    }

    void timer(const DurationType& duration, TimerCallback cb) {
        timer(current() + duration, cb);
    }

    void timer(const TimeType& time, TimerCallback cb) {
        boost::asio::deadline_timer* t = new boost::asio::deadline_timer(io_service, time);
        t->async_wait( boost::bind(&AsioTimer::handleTimer, this, _1, t, cb) );
    }

    TimeType current() {
        return boost::posix_time::microsec_clock::universal_time();
    }

private:
    void handleTimer(const boost::system::error_code& error, boost::asio::deadline_timer* t, TimerCallback cb) {
        delete t;
        cb();
    }

    boost::asio::io_service& io_service;
}; // class AsioTimer

#endif //_cesium_example_asio_timer_hpp_
